/*
 * @Description: 帮助模型获取正确日期的工具对象
 * @Author: 莫若省
 * @date: 2025/9/2
 *
 * 功能说明：
 * 1. 支持解析自然语言中的相对日期描述
 * 2. 支持中文数字和阿拉伯数字
 * 3. 支持未来/过去n天/月/年格式
 * 4. 支持"这周五"、"下周五"、"这星期X"、"下星期X"等表达
 * 5. 支持"二十日后"等中文数字+时间单位格式
 * 6. 返回对应的具体日期和时间
 */

import { MCPToolInterface } from "../../types/index.js";
import { z } from "zod";

// 日期关键词映射
const DATE_KEYWORDS: Record<string, number> = {
    '今天': 0, '当天': 0, '现在': 0, '当前': 0,
    '昨天': -1, '前天': -2, '大前天': -3,
    '明天': 1, '后天': 2, '大后天': 3,
    '前年': -730, '去年': -365, '今年': 0, '明年': 365, '后年': 730
};

// 中文数字映射（扩展支持更多中文数字）
const CHINESE_NUMBERS: Record<string, number> = {
    '零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5,
    '六': 6, '七': 7, '八': 8, '九': 9, '十': 10, '十一': 11,
    '十二': 12, '十三': 13, '十四': 14, '十五': 15, '十六': 16,
    '十七': 17, '十八': 18, '十九': 19, '二十': 20, '三十': 30,
    '四十': 40, '五十': 50, '六十': 60, '七十': 70, '八十': 80,
    '九十': 90, '两': 2, '百': 100, '千': 1000, '万': 10000,
    '廿': 20, '卅': 30, '卌': 40, '皕': 200
};

// 星期映射
const WEEKDAY_MAP: Record<string, number> = {
    '日': 0, '天': 0, '一': 1, '二': 2, '三': 3,
    '四': 4, '五': 5, '六': 6
};

const dateToolGenerator = (): MCPToolInterface => ({
    name: "日期计算器",
    description: "精准解析中文自然语言日期描述，支持相对时间、绝对时间、星期表达、中文数字日期等多种格式，返回具体的日期时间信息",
    prams: {
        text: z.string().describe("请输入自然语言日期描述，支持：1.相对时间(3天后/一个月前/二十日后) 2.绝对时间(下周一/这周五) 3.关键词(今天/明天/大后天) 4.时间段(未来7天/过去30天) 5.中文数字(三天后/二十日后/一百天后) "),
    },
    cb: async ({ text },extra) => {
        try {
            console.error(extra)
            const now = new Date();

            // 处理已知关键词
            if (DATE_KEYWORDS[text] !== undefined) {
                now.setDate(now.getDate() + DATE_KEYWORDS[text]);
                return formatDateResponse(now);
            }

            // 解析数字（支持中文和阿拉伯数字）
            const parseNumber = (str: string): number => {
                // 先尝试直接解析阿拉伯数字
                if (/^\d+$/.test(str)) {
                    return parseInt(str, 10);
                }

                // 解析中文数字
                let total = 0;
                let current = 0;

                for (const char of str) {
                    const num = CHINESE_NUMBERS[char];
                    if (num === undefined) continue;

                    if (num >= 10) {
                        if (current === 0) current = 1;
                        total += current * num;
                        current = 0;
                    } else {
                        current += num;
                    }
                }

                return total + current;
            };

            // 处理时间单位
            const handleTimeUnit = (date: Date, amount: number, unit: string, isFuture: boolean) => {
                const multiplier = isFuture ? 1 : -1;
                switch (unit) {
                    case '天': date.setDate(date.getDate() + amount * multiplier); break;
                    case '月': date.setMonth(date.getMonth() + amount * multiplier); break;
                    case '年': date.setFullYear(date.getFullYear() + amount * multiplier); break;
                    case '周': date.setDate(date.getDate() + amount * 7 * multiplier); break;
                }
            };

            // 匹配模式：未来/过去 + 数字 + 单位
            const timeMatch = text.match(/^(未来|过去|接下来|之前)([一二三四五六七八九十零两廿卅卌皕百千万\d]+)(天|个?月|年|周|个?星期)/);
            if (timeMatch) {
                const amount = parseNumber(timeMatch[2]);
                const unit = timeMatch[3].replace('个', '').replace('星期', '周');
                const isFuture = ['未来', '接下来'].includes(timeMatch[1]) ||
                    (timeMatch[1] !== '之前');
                handleTimeUnit(now, amount, unit, isFuture);
                return formatDateResponse(now);
            }

            // 匹配模式：数字 + 单位 + 前/后
            const relativeMatch = text.match(/^([一二三四五六七八九十零两廿卅卌皕百千万\d]+)(天|个?月|年|周|个?星期)(前|后|之后)/);
            if (relativeMatch) {
                const amount = parseNumber(relativeMatch[1]);
                const unit = relativeMatch[2].replace('个', '').replace('星期', '周');
                handleTimeUnit(now, amount, unit, relativeMatch[3] !== '前');
                return formatDateResponse(now);
            }

            // 处理星期几（基本格式）
            const weekdayMatch = text.match(/^星期([一二三四五六日天])/);
            if (weekdayMatch) {
                const targetDay = WEEKDAY_MAP[weekdayMatch[1]];
                const currentDay = now.getDay();
                const daysToAdd = (targetDay - currentDay + 7) % 7 || 7;
                now.setDate(now.getDate() + daysToAdd);
                return formatDateResponse(now);
            }

            // 处理"这周五"、"下周五"格式
            const thisNextWeekMatch = text.match(/^(这|下|本周|下周)(周|星期)([一二三四五六日天])/);
            if (thisNextWeekMatch) {
                const targetDay = WEEKDAY_MAP[thisNextWeekMatch[3]];
                const currentDay = now.getDay();

                let daysToAdd = (targetDay - currentDay + 7) % 7;

                if (thisNextWeekMatch[1] === '下' || thisNextWeekMatch[1] === '下周') {
                    daysToAdd += 7;
                }

                if (daysToAdd === 0 && (thisNextWeekMatch[1] === '下' || thisNextWeekMatch[1] === '下周')) {
                    daysToAdd = 7;
                }

                now.setDate(now.getDate() + daysToAdd);
                return formatDateResponse(now);
            }

            // 处理"这周X"、"下周X"格式（不带"期"字）
            const thisNextWeekShortMatch = text.match(/^(这|下)周([一二三四五六日天])/);
            if (thisNextWeekShortMatch) {
                const targetDay = WEEKDAY_MAP[thisNextWeekShortMatch[2]];
                const currentDay = now.getDay();

                let daysToAdd = (targetDay - currentDay + 7) % 7;

                if (thisNextWeekShortMatch[1] === '下') {
                    daysToAdd += 7;
                }

                if (daysToAdd === 0 && thisNextWeekShortMatch[1] === '下') {
                    daysToAdd = 7;
                }

                now.setDate(now.getDate() + daysToAdd);
                return formatDateResponse(now);
            }

            // 都没有命中,返回未命中提示,让模型重新总结
            return {
                content: [{
                    text: `无法解析日期描述，请重新提取关键词 如 今天 明天 后天 三天后 一个月后 未来N天 过去N天 星期X 这周五 下周一 二十日后 当前时间为:${now.toLocaleString('zh-CN')}`,
                    type: "text"
                }]
            }
        } catch (error) {
            console.error("日期处理错误:", error);
            return {
                content: [{
                    text: "无法解析日期描述，已返回当前日期和时间",
                    type: "text"
                }, {
                    text: new Date().toLocaleString(),
                    type: "text"
                }]
            };
        }
    }
});

export const date_tool = dateToolGenerator;

// 格式化日期响应
function formatDateResponse(date: Date) {
    return {
        content: [
            {
                text: `您查询的日期是: ${date.toLocaleDateString('zh-CN', {
                    year: 'numeric', month: 'long', day: 'numeric', weekday: 'long'
                })}`,
                type: "text"
            }
        ]
    };
}